package org.niugang.security.users.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义spring security身份验证机制
 *
 * @author Created by niugang on 2019/5/23/11:07
 */
@SuppressWarnings("Duplicates")
@Controller
@Slf4j
public class CustomAuthenticationController {

    private RequestCache requestCache = new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    /**
     * 当需要身份认证时，跳转到这里
     *
     * @param request  request
     * @param response response
     * @throws IOException IOException
     */
    @GetMapping("/authentication/require")
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public void requireAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        SavedRequest savedRequest = requestCache.getRequest(request, response);
        //通过浏览器访问的
        if (savedRequest != null) {
            List<String> accept = savedRequest.getHeaderValues("accept");
            if (accept != null && accept.size() > 0) {
                if (accept.get(0).contains(MediaType.TEXT_HTML_VALUE)) {
                    redirectStrategy.sendRedirect(request, response, "/authentication/login");
                }

            }
        }
        Map<String, Object> map = new HashMap<>(4);
        map.put("message", "访问的服务需要身份认证,请认证");
        map.put("status", HttpStatus.UNAUTHORIZED.value());
        map.put("timestamp", System.currentTimeMillis());
        ObjectMapper objectMapper = new ObjectMapper();
        //其他访问，如前后端分离，前端根据返回的状态码路由到对应的页面
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(map));

    }

    /**
     * 跳转到freemarker定义的登录页面
     *
     * @return String
     */
    @GetMapping("/authentication/login")
    public String login() {
        return "login";
    }
}
